using System.Collections;
using System.Collections.Generic;
using System;
using System.IO;
using UnityEngine;

public delegate void BlockEvent(int score);

public class BlockGenerator : MonoBehaviour
{
    //设置是否生成障碍物
    public bool creatWork = false;

    //设置障碍物预制体
    [SerializeField]
    private GameObject block;

    //关卡数据文件
    [SerializeField]
    private TextAsset BlockDatasFile;

    //关卡数据类及数据数组
    private class BlockData
    {
        public BlockData(float yPosition, float space, float generateInterval)
        {
            YPosition = yPosition;
            Space = space;
            GenerateInterval = generateInterval;
        }

        public float YPosition { get; private set; }
        public float Space { get; private set; }
        public float GenerateInterval { get; private set; }
    }
    private BlockData[] BlockDatas;

    //当前需要读取的数据行数
    private int currentReadLine = 0;

    //生成障碍物计时器
    private float intervalCount = 0;

    //设置障碍物向左移动的速度
    public float moveSpeed = 10;

    //设置障碍物宽度
    [SerializeField]
    private float blockWidth = 150;

    //障碍物列表
    public List<GameObject> allBlocks;

    //定义障碍物事件
    public event BlockEvent CrossBlock;

    // Start is called before the first frame update
    void Start()
    {
        //设置当前空物体位置，作为之后实例化障碍物的位置
        RectTransform parentCanvas = GetComponentInParent<RectTransform>();
        float localScreenWidth = Screen.width / parentCanvas.lossyScale.y;
        Vector3 instancePosition = new Vector3(localScreenWidth/2 + blockWidth/2, 0, 0);
        gameObject.transform.localPosition = instancePosition;

        //读取关卡数据文件并存入关卡数据数组
        string[] dataLines = BlockDatasFile.text.Split('\n');
        BlockDatas = new BlockData[dataLines.Length];
        for(int i = 0; i < dataLines.Length; i++)
        {
            string[] currentData = dataLines[i].Split(',');
            float yPosition = (float)Convert.ToDouble(currentData[0]);
            float spcae = (float)Convert.ToDouble(currentData[1]);
            float generateInterval = (float)Convert.ToDouble(currentData[2]);

            BlockDatas[i] = new BlockData(yPosition, spcae, generateInterval);
        }

        //在OnGameStart中注册匿名方法，激活创建障碍物
        GlobalEventManager.OnGameStart += () => { creatWork = true; };

        //在ReStartEvent中注册清除所有障碍物的方法
        GlobalEventManager.OnGameRestart += ClearAllBlocks;
        GlobalEventManager.OnGameRestart += () => { currentReadLine = 0; creatWork = false; intervalCount = 0; };

        //在OnGameOver中注册匿名方法，停止继续创建障碍物
        GlobalEventManager.OnGameOver += () => { creatWork = false; };
    }

    // Update is called once per frame
    void Update()
    {
        //游戏运行时，创建障碍物
        if (creatWork)
        {
            CreateBlock();
        }

        //遍历所以障碍物，让障碍物持续向左移动
        for(int i = allBlocks.Count - 1; i >= 0; i--)
        {
            GameObject block = allBlocks[i];
            BlockControll blockControll = block.GetComponent<BlockControll>();

            block.transform.localPosition -= new Vector3(moveSpeed * Time.deltaTime, 0, 0);

            //障碍物超出屏幕显示范围时，销毁障碍物
            if (block.transform.localPosition.x + blockControll.blockUp.rect.width / 2 < -Screen.width / 2)
            {
                allBlocks.Remove(block);
                Destroy(block);
            }

            //障碍物越过屏幕中心时，触发越过障碍物事件
            if (block.transform.localPosition.x < 0 && !blockControll.crossed)
            {
                blockControll.crossed = true;
                CrossBlock(1);
            }
        }
    }

    //实例化一个障碍物
    void CreateBlock()
    {
        //计时器归零时，实例化一个障碍物，并重置计时器。
        if (intervalCount > 0)
        {
            intervalCount -= Time.deltaTime;
        }
        else
        {
            BlockData blockData = GetBlockData();

            intervalCount = blockData.GenerateInterval;

            GameObject instanceBlock = Instantiate(block, gameObject.transform.position, Quaternion.identity, transform.parent);
            BlockControll blockControll = instanceBlock.GetComponent<BlockControll>();
            blockControll.space = blockData.Space;

            float yPosition = UnityEngine.Random.Range(-(Screen.height/2 - 200), Screen.height/2 - 200);
            blockControll.yPosition = blockData.YPosition;

            allBlocks.Add(instanceBlock);
        }
    }

    //获取一个障碍物的数据
    private BlockData GetBlockData()
    {
        int line = currentReadLine % BlockDatas.Length;
        currentReadLine++;
        return BlockDatas[line];
    }

    //清除所有障碍物
    public void ClearAllBlocks()
    {
        for (int i = allBlocks.Count - 1; i >= 0; i--)
        {
            GameObject block = allBlocks[i];
            allBlocks.Remove(block);
            Destroy(block);
        }
    }
}
